#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>

// 函数指针类型
typedef void (*func_t)();

#define NUM 5
func_t handlers[NUM+1];

// 如下是任务
void DownLoad()
{
    printf("我是一个下载的任务...\n");
}
void Flush()
{
    printf("我是一个刷新的任务...\n");
}
void Log()
{
    printf("我是一个记录日志的任务...\n");
}

// 注册
void registerHandler(func_t h[], func_t f)
{
    int i = 0;
    for(; i<NUM; i++)
    {
        if(h[i] == NULL) break;
    }
    if(i==NUM) return;
    h[i] = f;
    h[i+1] = NULL;
}


int main()
{
    registerHandler(handlers,DownLoad);
    registerHandler(handlers,Flush);
    registerHandler(handlers,Log);

    pid_t id = fork();
    if(id==0)
    {
        //子进程
        int cnt = 3;
        while(1)
        {
            sleep(3);
            printf("我是一个子进程, pid: %d, ppid: %d\n", getpid(), getppid());
            sleep(1);
            cnt--;
            //int* p = 0;
            //*p = 100;
            //int p = 100;
            //p /= 0;
        }
        exit(10);
    }
    //sleep(10);

    //父进程
    while(1)
    {
        int status = 0;
        pid_t rid = waitpid(id, &status, WNOHANG);
        if(rid > 0)
        {
            printf("wait success, rid: %d, exit code: %d, exit signal: %d\n", rid, WEXITSTATUS(status), status&0x7F);
            break;
        }
        else if(rid == 0)
        {
            // 函数指针进行回调处理
            int i = 0;
            for(; handlers[i] ; i++)
            {
                handlers[i]();
            }
            printf("本 轮 调 用 结 束，子 进 程 没 有 退 出\n");
            sleep(1);
        }
        else{
            printf("等 待 失 败\n");
            break;
        }
    }

    ////pid_t rid = wait(NULL);
    //int status = 0;
    //pid_t rid = waitpid(id,&status,0);
    //if(rid>0)
    //{
    //    if(WIFEXITED(status))
    //        printf("wait success, rid: %d, exit code: %d, exit signal: %d\n", rid, WEXITSTATUS(status), status&0x7F);
    //    else
    //        printf("子 进 程 退 出 异 常！\n");
    //    //printf("wait success, rid: %d, exit code: %d, exit signal: %d\n", rid, (status>>8)&0xFF, status&0x7F);
    //}
    //else{
    //    printf("wait fail: %d: %s\n",errno, strerror(errno));
    //}
    //sleep(10);

    return 0;
}

//#include <stdio.h>
//#include <stdlib.h>
//#include <errno.h>
//#include <string.h>
//#include <unistd.h>
//#include <sys/types.h>
//#include <sys/wait.h>
//
//int main()
//{
//    pid_t id = fork();
//    if(id==0)
//    {
//        //子进程
//        int cnt = 3;
//        while(cnt)
//        {
//            //sleep(3);
//            printf("我是一个子进程, pid: %d, ppid: %d\n", getpid(), getppid());
//            sleep(1);
//            cnt--;
//            //int* p = 0;
//            //*p = 100;
//            int p = 100;
//            p /= 0;
//        }
//        exit(10);
//    }
//    //sleep(10);
//
//    //父进程
//    //pid_t rid = wait(NULL);
//    int status = 0;
//    pid_t rid = waitpid(id,&status,0);
//    if(rid>0)
//    {
//        if(WIFEXITED(status))
//            printf("wait success, rid: %d, exit code: %d, exit signal: %d\n", rid, WEXITSTATUS(status), status&0x7F);
//        else
//            printf("子 进 程 退 出 异 常！\n");
//        //printf("wait success, rid: %d, exit code: %d, exit signal: %d\n", rid, (status>>8)&0xFF, status&0x7F);
//    }
//    else{
//        printf("wait fail: %d: %s\n",errno, strerror(errno));
//    }
//    //sleep(10);
//
//    return 0;
//}


//#include <stdio.h>
//#include <stdlib.h>
//#include <errno.h>
//#include <string.h>
//#include <unistd.h>
//
//int main()
//{
//    printf("Hello Linux!");
//    sleep(3);
//    _exit(1);
//    return 0;
//}

//#include <stdio.h>
//#include <stdlib.h>
//#include <errno.h>
//#include <string.h>
//#include <unistd.h>
//
//void fun()
//{
//    printf("fun begin!\n");
//    //exit(40);
//    _exit(4);
//    printf("fun end!\n");
//}
//
//int main()
//{
//    fun();
//    printf("Hello Linux\n");
//    return 0;
//}

//#include <stdio.h>
//#include <stdlib.h>
//#include <errno.h>
//#include <string.h>
//
//int main()
//{
//    for(int i=0;i<200;i++)
//    {
//        printf("%d->%s\n",i , strerror(i));
//    }
//    return 0;
//}

//#include <stdio.h>
//#include <stdlib.h>
//#include <errno.h>
//
//int main()
//{
//    FILE* fp = fopen("log.txt","r");
//    if(fp==NULL) return errno;
//
//    printf("Hello Linux\n");
//
//    fclose(fp);
//    return 0;
//}
